﻿using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Net.Http.Headers;

namespace NazTek.Core
{
    /// <summary>
    /// Provides for sending HTTP requests and receiving HTTP responses from a resource identified by a URI.
    /// </summary>
    public interface IHttpClient : IDisposable
    {
        /// <summary>
        /// Set web service context.
        /// </summary>
        /// <param name="context">Provides web service context information.</param>
        void SetContext(IServiceContext context);
        /// <summary>
        /// Send a GET request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <returns>Returns System.Threading.Tasks.Task&lt;T&gt;.The task object representing the asynchronous operation.</returns>
        Task<HttpResponseMessage> GetAsync(string requestUri);
        /// <summary>
        /// Send a POST request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// <typeparam name="T">Type of the object to serialize into the request body.</typeparam>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="value">Value of the object to serialize into the request body.</param>
        /// <returns>Returns System.Threading.Tasks.Task&lt;T&gt;.The task object representing the asynchronous operation.</returns>
        Task<HttpResponseMessage> PostAsJsonAsync<T>(string requestUri, T value);
    }
    /// <summary>
    /// Provides for sending HTTP requests and receiving HTTP responses from a resource identified by a URI.
    /// </summary>
    public class DefaultHttpClient : HttpClient, IHttpClient
    {
        /// <summary>
        /// Set web service context.
        /// </summary>
        /// <param name="context">Provides web service context information for base URI and media type.</param>
        public virtual void SetContext(IServiceContext context)
        {
            BaseAddress = new Uri(context.BaseUri);
            DefaultRequestHeaders.Accept.Clear();
            DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(context.DataTransferMedia));
        }
        /// <summary>
        /// Send a GET request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <returns>Returns System.Threading.Tasks.Task&lt;T&gt;.The task object representing the asynchronous operation.</returns>
        /// <remarks>
        /// This is a pass through method to <see cref="HttpClient.GetAsync(string)"/>.  
        /// The base method is not virtual, we are virtualizing it here to allow mock implementations.
        /// </remarks>
        public new virtual async Task<HttpResponseMessage> GetAsync(string requestUri)
        {
            return await base.GetAsync(requestUri);
        }
        /// <summary>
        /// Send a POST request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// <typeparam name="T">Type of the object to serialize into the request body.</typeparam>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="value">Value of the object to serialize into the request body.</param>
        /// <returns>Returns System.Threading.Tasks.Task&lt;T&gt;.The task object representing the asynchronous operation.</returns>
        /// <remarks>
        /// This is a pass through method to HttpClientExtensions.PostAsJsonAsync.  
        /// </remarks>
        public virtual async Task<HttpResponseMessage> PostAsJsonAsync<T>(string requestUri, T value)
        {
            return await HttpClientExtensions.PostAsJsonAsync(this, requestUri, value);
        }
    }
}